﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Pong
{
    public enum CollisionResult
    {
        TOP,
        BOTTOM,
        LEFT,
        RIGHT,
        NONE,
    };

    public class CollisionDetector
    {
        public static CollisionResult Line2Rect(Vector2D ls, Vector2D lf, Pawn p)
        {           
            // Assumes that the line intersects with the pawn
            Vector2D p1 = new Vector2D(p.X, p.Y);
            Vector2D p2 = new Vector2D(p.X + p.PawnDisplayer.ActualWidth, p.Y);
            Vector2D p3 = new Vector2D(p.X, p.Y + p.PawnDisplayer.ActualHeight);
            Vector2D p4 = new Vector2D(p.X + p.PawnDisplayer.ActualWidth, p.Y+p.PawnDisplayer.ActualHeight);

            // Top Edge
            if (Vec2LinesIntersect(ls, lf, p1, p2))
            {
                return CollisionResult.TOP;
            }
            else if (Vec2LinesIntersect(ls, lf, p3, p4))
            {
                return CollisionResult.BOTTOM;
            }
            else if (Vec2LinesIntersect(ls, lf, p2, p4))
            {
                return CollisionResult.RIGHT;
            }
            else
            {
                return CollisionResult.LEFT;
            }
        }

        public static bool Vec2LinesIntersect(Vector2D l1s, Vector2D l1f, Vector2D l2s, Vector2D l2f)
        {// Ripped out of Ogre3d example

            Vector2D v1 = new Vector2D(l1f.X - l1s.X, l1f.Y - l1s.Y );

            Vector2D v2 = new Vector2D( l2s.X - l1s.X, l2s.Y - l1s.Y );
            Vector2D v3 = new Vector2D( l2f.X - l1s.X, l2f.Y - l1s.Y );

            double crossProd1 = v1.CrossProduct(v2);
            double crossProd2 = v1.CrossProduct(v3);

            if ((crossProd1 > 0 && crossProd2 < 0) || (crossProd1 < 0 && crossProd2 > 0)
            || (crossProd1 == 0 && crossProd2 == 0))
            {

                v1 = new Vector2D( l2s.X - l2f.X, l2s.Y - l2f.Y );

                v2 = new Vector2D( l1s.X - l2f.X, l1s.Y - l2f.Y );
                v3 = new Vector2D( l1f.X - l2f.X, l1f.Y - l2f.Y );

                crossProd1 = v1.CrossProduct(v2);
                crossProd2 = v1.CrossProduct(v3);

                if ((crossProd1 > 0 && crossProd2 < 0) || (crossProd1 < 0 && crossProd2 > 0)
                || (crossProd1 == 0 && crossProd2 == 0))
                {
                    return true;
                }
            }
            return false;
        }

        public static CollisionResult RectInRect(Pawn p1, Pawn p2)
        {
            double p1H = p1.PawnDisplayer.ActualHeight;
            double p1W = p1.PawnDisplayer.ActualWidth;
            
            if (PointInRect(p1.X, p1.Y, p2))
            {// Top right corner
                Vector2D e = new Vector2D(p1.X, p1.Y);
                Vector2D s = new Vector2D(p1.X - p1.Velocity.X, p1.Y - p1.Velocity.Y );
                return Line2Rect(s, e, p2);
            }
            else if(PointInRect(p1.X + p1W, p1.Y, p2))
            {// Top left corner
                Vector2D e = new Vector2D(p1.X + p1W, p1.Y);
                Vector2D s = new Vector2D((p1.X + p1W) - p1.Velocity.X, p1.Y - p1.Velocity.Y);
                return Line2Rect(s, e, p2);
            }
            else if(PointInRect(p1.X, p1.Y + p1H, p2))
            {
                Vector2D e = new Vector2D(p1.X, p1.Y + p1H);
                Vector2D s = new Vector2D(p1.X - p1.Velocity.X, (p1.Y + p1H) - p1.Velocity.Y);
                return Line2Rect(s, e, p2);
            }
            else if(PointInRect(p1.X + p1W, p1.Y + p1H, p2))
            {
                Vector2D e = new Vector2D(p1.X + p1W, p1.Y + p1H);
                Vector2D s = new Vector2D((p1.X + p1W) - p1.Velocity.X, (p1.Y + p1H) - p1.Velocity.Y);
                return Line2Rect(s, e, p2);
            }
            return CollisionResult.NONE;
        }

        public static bool PointInRect(double X, double Y, Pawn p1)
        {
            double p1H = p1.PawnDisplayer.ActualHeight;
            double p1W = p1.PawnDisplayer.ActualWidth;

            if ((X >= p1.X && X <= (p1.X+p1W)) && (Y >= p1.Y && Y <= (p1.Y + p1H)))
            {
                return true;
            }
            return false;
        }

        
    }
}
